Namespace DataStream

    Friend Delegate Sub HandleControl(ByVal Control As Object)

    Friend Class StreamRuntimeControler
        Implements IDisposable

        Private m_Extensions As New StreamRuntimeCollection

        Private m_Remove As HandleControl

        Sub Initialise()
            Dim directory As String = Application.StartupPath & "\Extensions\"

            Try
                Dim files As String() = System.IO.Directory.GetFiles(directory, "*.dll")

                If Not files Is Nothing AndAlso files.Length > 0 Then
                    For Each file As String In files
                        Dim asm As Reflection.Assembly
                        ' Dim bFound As Boolean = False
                        Try
                            asm = Reflection.Assembly.LoadFrom(file)
                            For Each typeAsm As Type In asm.GetTypes
                                If Not typeAsm.GetInterface(GetType(IStreamRuntime).FullName) Is Nothing Then
                                    ' Type typeAsm.Fullname in asm.Fullname supports the interface
                                    Dim iObj As IStreamRuntime
                                    iObj = CType(asm.CreateInstance(typeAsm.FullName, True), IStreamRuntime)
                                    m_Extensions.Add(iObj)
                                    ' bFound = True
                                ElseIf Not typeAsm.GetInterface(GetType(IStreamControl).FullName) Is Nothing Then
                                    Dim iObj As IStreamControl
                                    iObj = CType(asm.CreateInstance(typeAsm.FullName, True), IStreamControl)
                                    RaiseEvent AddControl(iObj)
                                    'm_Extensions.Add(iObj)
                                End If
                            Next
                        Catch ex As Reflection.ReflectionTypeLoadException
                            Debug.Print("Unable to load assembly: " & file)
                        End Try

                        'If bFound Then
                        '    m_Assemblies.Add(asm)
                        'End If
                    Next

                    ' Add to stream controls
                    For Each obj As Object In m_Extensions
                        RaiseEvent AddControl(obj)
                        'If Not obj.GetType.GetInterface(GetType(IStreamRecieve).FullName) Is Nothing Then

                        'End If

                        If Not obj.GetType.GetInterface(GetType(IStreamControl).FullName) Is Nothing Then
                            Dim handler As IStreamRuntime = obj
                            ' Link the add/removes
                            AddHandler handler.AddControl, AddressOf Me.AddControlHandler
                            AddHandler handler.RemoveControl, AddressOf Me.RemoveControlHandler

                            ' Link in the exception handler
                            AddHandler handler.UnhandledException, AddressOf Me.UnhandleExceptionHandler

                            ' Display Message event handler
                            AddHandler handler.DisplayMessage, AddressOf Me.DisplayMessageHandler

                            ' Initialise the control
                            If CType(obj, IStreamRuntime).Initialise() Then

                            End If
                        End If
                    Next
                End If
            Catch ex As InvalidOperationException

            End Try
        End Sub

        Private disposedValue As Boolean = False        ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' TODO: free managed resources when explicitly called

                    For Each ext As IStreamRuntime In m_Extensions
                        Dim obj As Object = ext

                        If Not obj.GetType.GetInterface(GetType(IStreamRecieve).FullName) Is Nothing Then
                            RaiseEvent RemoveControl(obj)
                        End If

                        ext.Dispose()
                    Next
                End If

                ' TODO: free shared unmanaged resources
            End If
            Me.disposedValue = True
        End Sub

        Private Sub UnhandleExceptionHandler(ByVal sender As Object, ByVal e As System.EventArgs)
            RaiseEvent RuntimeExtensionException(sender, e)
        End Sub

        Private Sub AddControlHandler(ByVal sender As Object, ByVal Control As Object)
            RaiseEvent AddControl(Control)
        End Sub

        Private Sub RemoveControlHandler(ByVal sender As Object, ByVal Control As Object)
            RaiseEvent RemoveControl(Control)
        End Sub

        Private Sub DisplayMessageHandler(ByVal sender As Object, ByVal e As DataStream.DisplayMessageEventArgs)
            RaiseEvent DisplayMessage(sender, e)
        End Sub

        Friend Event RuntimeExtensionException(ByVal sender As Object, ByVal e As System.EventArgs)

        Friend Event AddControl(ByVal Control As Object)

        Friend Event RemoveControl(ByVal Control As Object)

        Friend Event DisplayMessage(ByVal sender As Object, ByVal e As DataStream.DisplayMessageEventArgs)

        ''' <summary>
        ''' Gets the IStreamRuntime objects
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RuntimeCollection() As StreamRuntimeCollection
            Get
                Return m_Extensions
            End Get
        End Property

#Region " IDisposable Support "
        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class

End Namespace

